package com.baiyu.netty;

import com.baiyu.model.*;
import com.baiyu.model.base.Message;
import com.baiyu.model.base.NullMsg;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
@Slf4j
// 直接从 WebSocketFrame 解码为 Message 对象
public class MocWebSocketMessageDecoder extends MessageToMessageDecoder<WebSocketFrame> {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        // 配置 Jackson
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Message.class, new MessageDeserializer());
        objectMapper.registerModule(module);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, WebSocketFrame frame, List<Object> out) throws Exception {
        // 只处理文本帧（忽略二进制帧、关闭帧等）
        if (frame instanceof TextWebSocketFrame) {
            // 1. 从 WebSocket 文本帧中提取 JSON 字符串
            String json = ((TextWebSocketFrame) frame).text();
            // 2. 直接将 JSON 反序列化为 Message 对象
            Message message=null;
            try{
                message = objectMapper.readValue(json, Message.class);
            }catch (JsonParseException e){
                message = new NullMsg();
                log.debug("--------消息解析异常------｛｝",e);
            }
            // 3. 传递给下一个 Handler
            out.add(message);
        } else {
            // 其他类型帧（如 BinaryWebSocketFrame、CloseWebSocketFrame）可根据需求处理
            // 示例：忽略非文本帧
            frame.release(); // 释放未处理的帧，避免内存泄漏
        }
    }

    // 内部类：自定义反序列化器（根据 "name" 字段映射具体 Message 类）
    private static class MessageDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<Message> {
        @Override
        public Message deserialize(com.fasterxml.jackson.core.JsonParser p, com.fasterxml.jackson.databind.DeserializationContext ctxt)
                throws java.io.IOException {
            com.fasterxml.jackson.databind.JsonNode node = p.getCodec().readTree(p);
            String name = node.get("name").asText();

            // 根据 name 映射到具体消息类
            switch (name) {
                case "initUser":
                    return p.getCodec().treeToValue(node, InitUser.class);
                case "sendMsgToUser":
                    return p.getCodec().treeToValue(node, SendMsgToUser.class);
                case "sendMsgToHouse":
                    return p.getCodec().treeToValue(node, SendMsgToHouse.class);
                case "sendMsgToAll":
                    return p.getCodec().treeToValue(node, SendMsgToAll.class);
                case "sendBinaryToUser":
                    return p.getCodec().treeToValue(node, SendBinaryToUser.class);
                case "sendBinaryToHouse":
                    return p.getCodec().treeToValue(node, SendBinaryToHouse.class);
                case "sendBinaryToAll":
                    return p.getCodec().treeToValue(node, SendBinaryToAll.class);
                // 补充其他消息类型...
                default:
                    throw new IllegalArgumentException("未知消息类型: " + name);
            }
        }
    }
}